{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "<a href=\"https://githubtocolab.com/gee-community/geemap/blob/master/docs/notebooks/51_cartoee_projections.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open in Colab\"/></a>\n",
    "\n",
    "Uncomment the following line to install [geemap](https://geemap.org) and [cartopy](https://scitools.org.uk/cartopy/docs/latest/installing.html#installing) if needed. Keep in mind that cartopy can be challenging to install. If you are unable to install cartopy on your computer, you can try Google Colab with this the [notebook example](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/notebooks/cartoee_colab.ipynb). \n",
    "\n",
    "See below the commands to install cartopy and geemap using conda/mamba:\n",
    "\n",
    "```\n",
    "conda create -n carto python=3.8\n",
    "conda activate carto\n",
    "conda install mamba -c conda-forge\n",
    "mamba install cartopy scipy -c conda-forge\n",
    "mamba install geemap -c conda-forge\n",
    "jupyter notebook\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install cartopy scipy\n",
    "# !pip install geemap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2",
   "metadata": {},
   "source": [
    "# Working with projections in cartoee\n",
    "\n",
    "`cartoee` is a lightweight module to aid in creatig publication quality maps from Earth Engine processing results without having to download data. The `cartoee` package does this by requesting png images from EE results (which are usually good enough for visualization) and `cartopy` is used to create the plots. Utility functions are available to create plot aethetics such as gridlines or color bars. **The notebook and the geemap cartoee module ([cartoee.py](https://geemap.org/cartoee)) were contributed by [Kel Markert](https://github.com/KMarkert). A huge thank you to him.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import ee\n",
    "import geemap\n",
    "from geemap import cartoee\n",
    "import cartopy.crs as ccrs\n",
    "\n",
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_initialize()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5",
   "metadata": {},
   "source": [
    "## Plotting an image on a map\n",
    "\n",
    "Here we are going to show another example of creating a map with EE results. We will use global sea surface temperature data for Jan-Mar 2018."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get an earth engine image of ocean data for Jan-Mar 2018\n",
    "ocean = (\n",
    "    ee.ImageCollection(\"NASA/OCEANDATA/MODIS-Terra/L3SMI\")\n",
    "    .filter(ee.Filter.date(\"2018-01-01\", \"2018-03-01\"))\n",
    "    .median()\n",
    "    .select([\"sst\"], [\"SST\"])\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# set parameters for plotting\n",
    "# will plot the Sea Surface Temp with specific range and colormap\n",
    "visualization = {\"bands\": \"SST\", \"min\": -2, \"max\": 30}\n",
    "# specify region to focus on\n",
    "bbox = [180, -88, -180, 88]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# plot the result with cartoee using a PlateCarre projection (default)\n",
    "ax = cartoee.get_map(ocean, cmap=\"plasma\", vis_params=visualization, region=bbox)\n",
    "cb = cartoee.add_colorbar(ax, vis_params=visualization, loc=\"right\", cmap=\"plasma\")\n",
    "\n",
    "ax.set_title(label=\"Sea Surface Temperature\", fontsize=15)\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9",
   "metadata": {},
   "source": [
    "### Mapping with different projections\n",
    "\n",
    "You can specify what ever projection is available within `cartopy` to display the results from Earth Engine. Here are a couple examples of global and regions maps using the sea surface temperature example. Please refer to the [`cartopy` projection documentation](https://scitools.org.uk/cartopy/docs/latest/reference/projections.html) for more examples with different projections."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# create a new Mollweide projection centered on the Pacific\n",
    "projection = ccrs.Mollweide(central_longitude=-180)\n",
    "\n",
    "# plot the result with cartoee using the Mollweide projection\n",
    "ax = cartoee.get_map(\n",
    "    ocean, vis_params=visualization, region=bbox, cmap=\"plasma\", proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(\n",
    "    ax, vis_params=visualization, loc=\"bottom\", cmap=\"plasma\", orientation=\"horizontal\"\n",
    ")\n",
    "\n",
    "ax.set_title(\"Mollweide projection\")\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# create a new Goode homolosine projection centered on the Pacific\n",
    "projection = ccrs.Robinson(central_longitude=-180)\n",
    "\n",
    "# plot the result with cartoee using the Goode homolosine projection\n",
    "ax = cartoee.get_map(\n",
    "    ocean, vis_params=visualization, region=bbox, cmap=\"plasma\", proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(\n",
    "    ax, vis_params=visualization, loc=\"bottom\", cmap=\"plasma\", orientation=\"horizontal\"\n",
    ")\n",
    "\n",
    "ax.set_title(\"Robinson projection\")\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# create a new Goode homolosine projection centered on the Pacific\n",
    "projection = ccrs.InterruptedGoodeHomolosine(central_longitude=-180)\n",
    "\n",
    "# plot the result with cartoee using the Goode homolosine projection\n",
    "ax = cartoee.get_map(\n",
    "    ocean, vis_params=visualization, region=bbox, cmap=\"plasma\", proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(\n",
    "    ax, vis_params=visualization, loc=\"bottom\", cmap=\"plasma\", orientation=\"horizontal\"\n",
    ")\n",
    "\n",
    "ax.set_title(\"Goode homolosine projection\")\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# create a new orographic projection focused on the Pacific\n",
    "projection = ccrs.EqualEarth(central_longitude=-180)\n",
    "\n",
    "# plot the result with cartoee using the orographic projection\n",
    "ax = cartoee.get_map(\n",
    "    ocean, vis_params=visualization, region=bbox, cmap=\"plasma\", proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(\n",
    "    ax, vis_params=visualization, loc=\"right\", cmap=\"plasma\", orientation=\"vertical\"\n",
    ")\n",
    "\n",
    "ax.set_title(\"Equal Earth projection\")\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# create a new orographic projection focused on the Pacific\n",
    "projection = ccrs.Orthographic(-130, -10)\n",
    "\n",
    "# plot the result with cartoee using the orographic projection\n",
    "ax = cartoee.get_map(\n",
    "    ocean, vis_params=visualization, region=bbox, cmap=\"plasma\", proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(\n",
    "    ax, vis_params=visualization, loc=\"right\", cmap=\"plasma\", orientation=\"vertical\"\n",
    ")\n",
    "\n",
    "ax.set_title(\"Orographic projection\")\n",
    "\n",
    "ax.coastlines()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15",
   "metadata": {},
   "source": [
    "### Warping artifacts\n",
    "\n",
    "Often times global projections are not needed so we use specific projection for the map that provides the best view for the geographic region of interest. When we use these, sometimes image warping effects occur. This is because `cartoee` only requests data for region of interest and when mapping with `cartopy` the pixels get warped to fit the view extent as best as possible. Consider the following example where we want to map SST over the south pole:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# Create a new region to focus on\n",
    "spole = [180, -88, -180, 0]\n",
    "\n",
    "projection = ccrs.SouthPolarStereo()\n",
    "\n",
    "# plot the result with cartoee focusing on the south pole\n",
    "ax = cartoee.get_map(\n",
    "    ocean, cmap=\"plasma\", vis_params=visualization, region=spole, proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(ax, vis_params=visualization, loc=\"right\", cmap=\"plasma\")\n",
    "\n",
    "ax.coastlines()\n",
    "ax.set_title(\"The South Pole\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17",
   "metadata": {},
   "source": [
    "As you can see from the result there are warping effects on the plotted image. There is really no way of getting around this (other than requesting a larger extent of data which may not always be the case). \n",
    "\n",
    "So, what we can do is set the extent of the map to a more realistic view after plotting the image as in the following example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(15, 10))\n",
    "\n",
    "# plot the result with cartoee focusing on the south pole\n",
    "ax = cartoee.get_map(\n",
    "    ocean, cmap=\"plasma\", vis_params=visualization, region=spole, proj=projection\n",
    ")\n",
    "cb = cartoee.add_colorbar(ax, vis_params=visualization, loc=\"right\", cmap=\"plasma\")\n",
    "\n",
    "ax.coastlines()\n",
    "ax.set_title(\"The South Pole\")\n",
    "\n",
    "# get bounding box coordinates of a zoom area\n",
    "zoom = spole\n",
    "zoom[-1] = -20\n",
    "\n",
    "# convert bbox coordinate from [W,S,E,N] to [W,E,S,N] as matplotlib expects\n",
    "zoom_extent = cartoee.bbox_to_extent(zoom)\n",
    "\n",
    "# set the extent of the map to the zoom area\n",
    "ax.set_extent(zoom_extent, ccrs.PlateCarree())\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernel_info": {
   "name": "python3"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
